Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

HTTP 连接与版本演进

复习

  • HTTP 请求与响应:请求-响应模型
  • 套接字:请求由 TCP 连接承载
  • TCP 为什么需要连接:建立连接本身有开销

TL;DR

  • 早期每个请求都新建一次连接,开销很大
  • 持久连接让多个请求复用同一条连接
  • 多路复用进一步让多个请求并行、互不阻塞
  • 版本演进的主线,就是不断减少等待与开销

正文

  HTTP 的每个请求,都要通过一条传输层连接来传递。那么,一个网页要取几十个资源(图片、样式、脚本),难道要建几十次连接?

  这正是 HTTP 版本演进要解决的核心问题。

每请求一连接的时代

  最早的 HTTP/1.0,基本是“一次请求,一条连接”:请求完就关,下个请求再重新建立。

  问题很明显:建立连接本身有成本(三次握手、慢启动),如果每个小资源都来一遍,大量时间都花在“准备连接”上,而不是真正传数据。这就像每买一样东西都重新排一次队,效率极低。

持久连接

  HTTP/1.1 引入了持久连接(keep-alive):一条连接建立后,可以反复用来发多个请求,用完先不关。

  这省掉了大量重复的握手开销。

  但它带来一个新问题:在一条连接上,请求通常还得一个接一个地处理。前一个没处理完,后面的就得排队等——哪怕它们互不相关。这叫“队头阻塞”。只要队首那个请求慢,后面全被拖住。

多路复用

  为了打破排队,HTTP/2 引入了多路复用:把请求拆成一个个小帧,打上标记,在同一条连接上交错发送。接收方按标记重新拼装,于是多个请求可以并行进行,互不阻塞

  再往后,HTTP/3 干脆换了底层传输方式(基于 UDP 的 QUIC),进一步减少连接建立和丢包恢复的等待。

  把这条演进线串起来看,主线非常清晰:一切都是为了减少等待、降低开销。 手段在变,目标没变。

思考题 1

  每次请求都新建 TCP 连接,代价主要体现在哪里?

思考题 2

  HTTP/2 的多路复用,解决了 HTTP/1.1 的什么问题?

小结

知识点

  • HTTP/1.0 每请求新建连接,开销大
  • HTTP/1.1 用持久连接复用连接
  • 一条连接上仍可能存在队头阻塞
  • HTTP/2 多路复用让请求并行进行

参考资料

  1. Wikipedia(zh):HTTP/2:支持多路复用的 HTTP 版本
  2. Wikipedia(zh):HTTP持久连接:在同一连接上发送多个请求

思考题答案(仅供参考)

思考题 1

  代价在建立连接本身:需要三次握手,还可能经历慢启动等阶段,在真正传数据之前就要花掉若干往返时间。资源多时,这些开销会被反复叠加,明显拖慢加载。

思考题 2

  解决了 HTTP/1.1 的队头阻塞:在一条连接上,前面的请求没完成会拖住后面的。多路复用把请求拆成小帧交错发送,使多个请求在同一条连接上并行处理,互不阻塞。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪